home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Visual Basic Source Code
/
Visual Basic Source Code.iso
/
vbsource
/
rpcdcpro
/
client.cpp
next >
Wrap
C/C++ Source or Header
|
1998-08-07
|
9KB
|
254 lines
//-----------------------------------------------------------------------------
// This program illustrates a simple tcp/udp client implementation
//-----------------------------------------------------------------------------
#ifdef WIN32
#include <windows.h>
#endif
#include <stdio.h>
#include <time.h>
#include <rpcdc.h>
//-----------------------------------------------------------------------------
// Here is a definition of a structure that must be transmitted to the server
// One possibility is to develop a specific XDR function, used with transmit/
// receive functions
//-----------------------------------------------------------------------------
typedef struct _TEST {
int i1;
int i2;
int i3;
float f;
double d;
} TEST;
//-----------------------------------------------------------------------------
// First write the XDR function - standard structure
// The parameters are as follows :
// h : (void *) points to the host binary representation of the data
// n : (void *) points to the network binary representation of the data
// code : indicates the operation to perform (3 possibilities)
// --> XDR_ENCODE : conversion h -> n
// --> XDR_DECODE : conversion n -> h
// --> XDR_MEMORY : just returns the size of the object
//-----------------------------------------------------------------------------
size_t _xdr_TEST (void *h, void *n, int code)
{
TEST *hi=(TEST *)h; // first convert pointers
char *ni=(char *)n;
size_t size;
switch (code) {
case XDR_ENCODE:
case XDR_DECODE:
size=_xdr_int(NULL,NULL,XDR_MEMORY);
_xdr_int((void *)&hi->i1,(void *)ni,code); ni+=size;
_xdr_int((void *)&hi->i2,(void *)ni,code); ni+=size;
_xdr_int((void *)&hi->i3,(void *)ni,code); ni+=size;
size=_xdr_float(NULL,NULL,XDR_MEMORY);
_xdr_float((void *)&hi->f,(void *)ni,code); ni+=size;
size=_xdr_double(NULL,NULL,XDR_MEMORY);
_xdr_double((void *)&hi->d,(void *)ni,code); ni+=size;
return 0;
case XDR_MEMORY:
default:
return 3*_xdr_int(NULL,NULL,XDR_MEMORY)+
_xdr_float(NULL,NULL,XDR_MEMORY)+
_xdr_double(NULL,NULL,XDR_MEMORY);
}
}
//-----------------------------------------------------------------------------
// Now the function to send a TEST structure becomes very simple !
// The following example returns 1 if success, 0 if a problem occurs.
// Binary conversion is automatically performed through the XDR routine
// written above.
// Warning : remember to call _rpc_flush() !
//-----------------------------------------------------------------------------
int _rpcsend_TEST (SOCKET Socket,
RPC_MSG *rpc_msg, XDR_BUFFER *xdr_buffer,
TEST *TestParameter)
{
return _rpcsend_buffer(Socket,rpc_msg,xdr_buffer,TestParameter,_xdr_TEST)==
_xdr_TEST(NULL,NULL,XDR_MEMORY);
}
//-----------------------------------------------------------------------------
// Similarly, the function to receive a TEST structure is also simple.
// Binary conversion is automatically performed through the XDR routine
// written above.
//-----------------------------------------------------------------------------
int _rpcrecv_TEST (SOCKET Socket,
XDR_BUFFER *xdr_buffer,
TEST *TestParameter)
{
return _rpcrecv_buffer(Socket,xdr_buffer,TestParameter,_xdr_TEST)==
_xdr_TEST(NULL,NULL,XDR_MEMORY);
}
//-----------------------------------------------------------------------------
// tcp client implementation
//-----------------------------------------------------------------------------
void mainTCP (char *server, char *service)
{
SOCKET Socket; // to communicate with the server
RPC_MSG rpc_msg; // for transmission buffering
XDR_BUFFER xdr_buffer; // for XDR buffering
char msg[256];
int ans;
time_t t;
TEST Test;
time(&t);
// Initialization of the TEST structure
Test.i1=10;
Test.i2=17;
Test.i3=25;
Test.f=3.14159f;
Test.d=2.7182818;
// Connection request to the specified server, with the specified service
Socket=_StartTCPClient(server,
service,
10,
&rpc_msg,
&xdr_buffer);
// An error occured, or the connection has been rejected
if (Socket==0) {
_GetErrMsg(msg);
printf("%s\n",msg);
return;
}
// Now the connection has been accepted !
// The first int (value 1) corresponds to the first rpc message transmitted to the server
_rpcsend_int(Socket,&rpc_msg,&xdr_buffer,1);
// This message also uses an additionnal parameter (int) : here the local time
_rpcsend_int(Socket,&rpc_msg,&xdr_buffer,(int)t);
// The last part of the message is made of the TEST structure defined above
_rpcsend_TEST(Socket,&rpc_msg,&xdr_buffer,&Test);
// flushing is required !
_rpc_flush(Socket,&rpc_msg);
// Now I am waiting for the answer coming from the server !
// In this example, the first int is modified and returned, same for the TEST structure.
_rpcrecv_int(Socket,&xdr_buffer,&ans);
_rpcrecv_TEST(Socket,&xdr_buffer,&Test);
printf("Message sent to server : %d\n",t);
printf("Server answered : %d\n",ans);
printf("New TEST : %d %d %d %g %lg\n",Test.i1,Test.i2,Test.i3,Test.f,Test.d);
// OK ! seems to work, bye !
_StopTCPClient(Socket,&rpc_msg,&xdr_buffer);
}
//-----------------------------------------------------------------------------
// udp client implementation
//-----------------------------------------------------------------------------
void mainUDP (char *service)
{
SOCKET udpSocket;
sockaddr_in bcast_addr,src_addr;
long int udpQuery;
int end,stat,len;
struct hostent *host;
time_t t1,t2;
struct timeval timeout={0,0};
char sz_info[256];
struct {
long int udpResponse;
char szb[128];
} udp;
// Creation of the socket corresponding to the specified service
udpSocket=_StartUDPClient(service,10,&bcast_addr);
if (udpSocket==0) {
_GetErrMsg(sz_info);
printf("%s\n",sz_info);
return;
}
// The udp message is 32 bits long, the value is just 1 in this example
udpQuery=htonl(1);
stat=sendto(udpSocket,(char *)&udpQuery,sizeof(long int),0,
(const struct sockaddr *)&bcast_addr,sizeof(sockaddr_in));
if (stat!=sizeof(long int)) {
_StopUDPClient(udpSocket);
return;
}
// Now I am waiting for answers coming from the different servers, max. delay 10 seconds
time(&t1);
end=0;
do {
switch (_socket_ready_r(udpSocket,&timeout)) {
case -1: // this is an error !
end=1;
break;
case 0: // no error, socket not ready !
time(&t2);
end=(t2-t1)>10;
break;
default: // no error, socket ready !
len=sizeof(src_addr);
stat=recvfrom(udpSocket,(char *)&udp,sizeof(udp),0,
(struct sockaddr *)&src_addr,&len);
if (stat==sizeof(udp)) {
udp.udpResponse=ntohl(udp.udpResponse);
switch (udp.udpResponse) {
case 2: // the server answers 2 (1+udpQuery) : good !
strcpy(sz_info,udp.szb);
break;
default:
strcpy(sz_info,"");
}
if (strlen(sz_info)!=0) {
host=gethostbyaddr((char *)&src_addr.sin_addr,sizeof(struct in_addr),PF_INET);
if (host!=NULL) printf("%s : ",host->h